﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Drawing;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
using System.Data;
namespace balace_project_new
{
    class Comunication
    {
        string Display_On = "ON\r\n";
        string Display_Off = "OFF\r\n"; // terminator chacraters are /r/n
        string Print = "PRT\r\n"; // request data
        string Rezero = "R\r\n";
        //input
        public int NumberOfGateway;
        public int IpIndex;
        public Data.BalanceProperties[] structBalancePro;
        //output
        public int count;
        public bool[] DataCome;
        public bool[] BalanceStatus;
        public bool[] GatewayStatus;
        public int NumberOfGatewayConnected = 0;
        public int NumberOfBalanceConnected = 0;
        public Data.revData[] structData;
            // function
            // init()
            // scan()
            // comamnd(string command, int balanceID)
        // private
        int cusor;      
        string[] ServerIp;
        public  Socket[] client;
        private static byte[] data = new byte[1024];
        //======================================================================================================
        public void init()
        {
            BalanceStatus = new bool[NumberOfGateway];
            GatewayStatus = new bool[NumberOfGateway];
            DataCome = new bool[NumberOfGateway];
            client = new Socket[NumberOfGateway];
            ServerIp = new string[NumberOfGateway];
            structData = new Data.revData[NumberOfGateway];
            for (int j = 0; j < NumberOfGateway; j++)
            {
                ServerIp[j] = "192.168.1." + IpIndex.ToString();
                BalanceStatus[j] = false;
                GatewayStatus[j] = false;
            }
        }
        Thread t1;
        public void scan()
        {
            t1 = new Thread(new ThreadStart(tt));
            t1.Start();
        }
        private void tt()
        {
            for (cusor = 0; cusor < NumberOfGateway; cusor++)
            {
                if (GatewayStatus[cusor] == false)
                {
                    client[cusor] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IPEndPoint iep = new IPEndPoint(IPAddress.Parse(ServerIp[cusor]), 1024);
                    client[cusor].BeginConnect(iep, new AsyncCallback(Connected), client[cusor]);
                    t1.Suspend();
                }
            }
            t1.Abort();
        }
        void Connected(IAsyncResult iar)
        {
            client[cusor] = (Socket)iar.AsyncState;
            try
            {
                client[cusor].EndConnect(iar);
                GatewayStatus[cusor] = true;
                NumberOfGatewayConnected++;
                Thread receiver = new Thread(new ThreadStart(ReceiveData));
                receiver.Start();
                byte[] mes = ASCIIEncoding.ASCII.GetBytes(Print);
                client[cusor].BeginSend(mes, 0, mes.Length, 0, new AsyncCallback(SendData), client[cusor]);
            }
            catch (SocketException)
            {
                var m = MessageBox.Show("Không kết nối được đến 192.168.1." + (IpIndex + cusor).ToString(), "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                GatewayStatus[cusor] = false;
                t1.Resume();
                return;
            }
 
        }
        void SendData(IAsyncResult iar)
        {
            Socket remote = (Socket)iar.AsyncState;
            int sent = remote.EndSend(iar);
        }
        void ReceiveData()
        {
            int recv;
            int temp = cusor;
            string strdata = "";
            t1.Resume();
            while(true)
            {
                try
                {
                    recv = client[temp].Receive(data);
                    if(BalanceStatus[temp] == false) BalanceStatus[temp] = true;      
                    if (recv == 9)
                    {
                        count++;
                        strdata = Encoding.ASCII.GetString(data, 0, 7);

                        structData[temp].BalanceIP = ((IPEndPoint)client[temp].RemoteEndPoint).Address.ToString();
                        structData[temp].BalanceID = structBalancePro[temp].BalanceID;
                        float.TryParse(strdata, out structData[temp].Weight);
                        structData[temp].Sequence++;
                        structData[temp].Time = new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
                        structData[temp].WeightErr = structData[temp].Weight - structBalancePro[temp].Weight;
                        structData[temp].Err = structData[temp].WeightErr / structBalancePro[temp].Weight * 100;
                        if (Math.Abs(structData[temp].Err) > structBalancePro[temp].Err) structData[temp].Quality = "Lỗi";
                        else structData[temp].Quality = "OK";
                        DataCome[temp] = true;
                    }

                }
                catch (SocketException)
                {
                    GatewayStatus[temp] = false;
                    BalanceStatus[temp] = false;
                    return;
                }
            }

 
        }
        public void Command(string s, int BalanceID)
        {
            byte[] mes ;
            s = s.ToUpper();
            if (s == "ON")
            {
                mes = ASCIIEncoding.ASCII.GetBytes(Display_On);
                client[BalanceID - 1].BeginSend(mes, 0, mes.Length, 0, new AsyncCallback(SendData), client[BalanceID - 1]);
            }
            if (s == "OFF")
            {
                mes = ASCIIEncoding.ASCII.GetBytes(Display_Off);
                client[BalanceID - 1].BeginSend(mes, 0, mes.Length, 0, new AsyncCallback(SendData), client[BalanceID - 1]);
            }
            if (s == "ZERO")
            {
                mes = ASCIIEncoding.ASCII.GetBytes(Rezero);
                client[BalanceID - 1].BeginSend(mes, 0, mes.Length, 0, new AsyncCallback(SendData), client[BalanceID - 1]);
            }
            
        }
    }
}
